using System;
using System.Collections.Generic;
using CustomerContactSystem.Core.Model;
using sdcc.FixYourStreetDotNet;

namespace CustomerContactSystem.Core.AppServices.FixYourStreet {
    public class FixYourStreetService : IFixYourStreetService {
        private string _errorMessage;
        public string FysUrl { get; set; }
        public string FysFolder { get; set; }
        public string FysApiVersion { get; set; }

        public IEnumerable<FixYourStreetIncident> GetLatestIncidents(int maxId) {
            if (!SettingsAreValid()) {
                throw new Exception(_errorMessage);
            }

            var fysClient = new FixYourStreetClient(FysUrl, FysFolder, FysApiVersion);

            return fysClient.GetIncidentsGreaterThanId(maxId);
        }

        public IEnumerable<FixYourStreetComment> GetLatestComments(int maxId) {
            if (!SettingsAreValid()) {
                throw new Exception(_errorMessage);
            }

            var fysClient = new FixYourStreetClient(FysUrl, FysFolder, FysApiVersion);
            return fysClient.GetCommentsGreaterThan(maxId, true);
        }

        public void SubmitStatusUpdate(int incidentId, string status) {
            if (!SettingsAreValid()) {
                throw new Exception(_errorMessage);
            }

            var fysClient = new FixYourStreetClient(FysUrl, FysFolder, FysApiVersion);
            var fysStatus = FixYourStreetClient.IncidentStatus.Any;
            switch (status) {
                case "O":
                    fysStatus = FixYourStreetClient.IncidentStatus.Open;
                    break;
                case "P":
                    fysStatus = FixYourStreetClient.IncidentStatus.InProgress;
                    break;
                case "C":
                    fysStatus = FixYourStreetClient.IncidentStatus.Closed;
                    break;
                case "M":
                    fysStatus = FixYourStreetClient.IncidentStatus.ClosedWithCommitment;
                    break;
            }

            var response = fysClient.UpdateIncidentStatus(incidentId, fysStatus);

            if (response.ErrorCode > 0) {
                throw new Exception(response.ErrorDescription);
            }
        }

        public int SubmitComment(int incidentId, string author, string comment) {
            if (!SettingsAreValid()) {
                throw new Exception(_errorMessage);
            }

            var fysClient = new FixYourStreetClient(FysUrl, FysFolder, FysApiVersion);

            var response = fysClient.SendComment(new FixYourStreetComment
                {
                    CommentAuthor = author,
                    CommentDescription = comment,
                    IncidentId = incidentId
                });

            if (response.ErrorCode > 0) {
                throw new Exception(response.ErrorDescription);
            }
            return response.NewId;
        }

        public void DeleteComment(int commentId) {
            if (!SettingsAreValid()) {
                throw new Exception(_errorMessage);
            }

            var fysClient = new FixYourStreetClient(FysUrl, FysFolder, FysApiVersion);

            var response = fysClient.DeleteComment(commentId);

            if (response.ErrorCode > 0) {
                throw new Exception(response.ErrorDescription);
            }
        }

        public IEnumerable<Enquiry> MapFixYourStreetIncidentToEnquiry(FixYourStreetIncident incident, Dictionary<int, EnquiryCategory> categoryMatchUps, EnquiryClassification classification, EnquirySource source, User submitter) {
            var enquiries = new List<Enquiry>();

            foreach (var fysCategory in incident.Categories) {
                if (categoryMatchUps.ContainsKey(fysCategory.Id)) {
                    enquiries.Add(new Enquiry
                        {
                            Category = categoryMatchUps[fysCategory.Id],
                            Classification = classification,
                            CurrentStatus = "Submitted by " + submitter.DisplayName,
                            DateOfEnquiry = DateTime.Now.AddMinutes(-1),
                            Deadline = DateTime.Now.AddHours(48),
                            EnquiryDetail = incident.Description,
                            FirstResponseTime = 0,
                            FixYourStreetId = incident.Id,
                            IsConfidential = false,
                            IsMediaEnquiry = false,
                            Source = source,
                            SubmittedBy = submitter,
                            SubmittedByDepartment = submitter.Department,
                            SubmittedByGroup = submitter.UserGroup
                        });
                }
            }

            return enquiries;
        }

        private bool SettingsAreValid() {
            _errorMessage = "";
            if (string.IsNullOrEmpty(FysUrl)) {
                _errorMessage += "Fix Your Street Url not set\n";
            }

            if (string.IsNullOrEmpty(FysFolder)) {
                _errorMessage += "Fix Your Street Folder not set\n";
            }

            if (string.IsNullOrEmpty(FysApiVersion)) {
                _errorMessage += "Fix Your Street Api Version not set\n";
            }

            return string.IsNullOrEmpty(_errorMessage);
        }
    }
}